﻿using WenAntdUI;
using WenAntdUI.Settings;

namespace WenAntdUI;

/// <summary>
/// 系统参数配置类
/// </summary>
public static class AppSettings
{
    private static readonly IFreeSql? freeSql;


    private static IFreeSql GetFreeSql()
    {
        if (freeSql == null)
        {
            var fsql = new FreeSql.FreeSqlBuilder()
               .UseConnectionString(global::FreeSql.DataType.Sqlite, "DataSource=settings.db")
               .UseAdoConnectionPool(true)
#if DEBUG
               .UseMonitorCommand(cmd => Console.WriteLine($"Setting Sql：{cmd.CommandText}\r\n"))
#endif
               .Build();
            fsql.CodeFirst.SyncStructure<Setting>();
            return fsql;
        }
        else
        {
            return freeSql;
        }
    }

    private static List<Setting>? settings;

    /// <summary>
    /// 本地设置数据库
    /// </summary>
    public static IFreeSql FreeSql => GetFreeSql();

    /// <summary>
    /// 全部设置内容
    /// </summary>
    public static List<Setting> Settings => settings ??= FreeSql.Select<Setting>().ToList();

    /// <summary>
    /// 获取设置值，若存在设置，读取数据中的值并转换指定类型，不存在创建并返回初始化指定值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="name"></param>
    /// <param name="value"></param>
    /// <param name="displayname"></param>
    /// <param name="groupname"></param>
    /// <param name="typ"></param>
    /// <returns></returns>
    public static T? GetOrSet<T>(string name, T value, string displayname, string groupname, SettingTyp typ = SettingTyp.None)
    {
        var stt = GetSetting(name);
        if (stt == null)
        {
            Set(name, value, displayname, groupname, typ);
            return value;
        }
        return Get<T>(name);
    }

    /// <summary>
    /// 获取设置实例
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static Setting? GetSetting(string name) =>
        Settings.Where(t => t.Name.Equals(name, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();


    /// <summary>
    /// 获取指定存储字体信息
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static Font GetFont(string name) => Get<Font>(name)!;


    /// <summary>
    /// 获取设置String值
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static string? GetString(string name) => GetSetting(name)?.Value;

    /// <summary>
    /// 获取设置Bool值
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static bool GetBool(string name) => Get<bool>(name);

    /// <summary>
    /// 设置变量值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="name"></param>
    /// <param name="t"></param>
    /// <param name="displayname"></param>
    /// <param name="groupName"></param>
    /// <param name="typ"></param>
    /// <param name="ishide"></param>
    public static void Set<T>(string name, T t,
        string displayname = "", string groupName = "",
        SettingTyp typ = SettingTyp.None,
        bool ishide = false)
    {
        var sel = Get<T>(name);
        if (Equals(sel, t))
            return;//数据一致，不更新本地存储

        var sttTyp = typ;
        var type = typeof(T);
        var items = string.Empty;
        var value = string.Empty;
 if (type == typeof(bool))
        {
            value = t?.ToString();
            sttTyp = SettingTyp.Bool;
        }
        else if (type == typeof(int))
        {
            value = t?.ToString();
            sttTyp = SettingTyp.Number;
        }
        else if (type.IsEnum)
        {
            items = string.Join(",", type.GetEnumNames());
            sttTyp = SettingTyp.Down;
            value = t.ToString();
        }
        else
        {
            if (sttTyp == SettingTyp.None)
            {
                sttTyp = SettingTyp.String;
            }

            value = t?.ToString() ?? "";
        }

        var stt = Settings.Where(t => t.Name.Equals(name, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
        if (stt == null)
        {
            stt = new Setting()
            {
                DisplayName = displayname,
                Name = name,
                Value = value,
                GroupName = groupName,
                Typ = sttTyp,
            };
            FreeSql.Insert<Setting>().AppendData(stt).ExecuteEffects();
        }
        else
        {
            stt.Value = value;
            if (!string.IsNullOrWhiteSpace(displayname))
            {
                stt.DisplayName = displayname;
            }
            if (!string.IsNullOrWhiteSpace(groupName))
            {
                stt.GroupName = groupName;
            }
            FreeSql.Update<Setting>().SetSource(stt).ExecuteAffrows();
        }
        settings = null; // 清除缓存
    }

    /// <summary>
    /// 获取设置值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="name"></param>
    /// <returns></returns>
    public static T? Get<T>(string name)
    {
        var type = typeof(T);
        var underlyingType = Nullable.GetUnderlyingType(type) ?? type;
        var stt = GetSetting(name);
        if (stt?.Value is null)
        {
            return default;
        }
        var input = stt.Value;

        try
        {
            // 处理Color类型
            if (underlyingType == typeof(Color))
            {
                return (T)(object)ColorTranslator.FromHtml(input);
            }

            // 处理布尔类型（如"true"或"1"）
            else if (underlyingType == typeof(bool))
            {
                return (T)(object)bool.Parse(input);
            }

            // 处理枚举类型
            else if (underlyingType.IsEnum)
            {
                return (T)Enum.Parse(type, input, true);
            }

            // 处理Image类型
            else if (underlyingType == typeof(Image))
            {
                var bytes = Convert.FromBase64String(input);
                using var ms = new MemoryStream(bytes);
                return (T)(object)Image.FromStream(ms);
            }
            //字体
            else if (underlyingType == typeof(Font))
            {
                Font font()
                {
                    try
                    {
                        return (Font)new FontConverter().ConvertFromString(stt.Value);
                    }
                    catch { return SystemFonts.DefaultFont; }
                }
                return (T)(object)font();
            }

            // 处理基础类型（int/float/string等）
            if (underlyingType == typeof(string))
            {
                return (T)(object)input;
            }

            // 处理基础类型（int/float等）
            return (T)Convert.ChangeType(input, type);
        }
        catch
        {
            return default;
        }
    }

    /// <summary>
    /// 删除缓存
    /// </summary>
    public static void DeleteCache()
    {
        settings = null;
    }

    /// <summary>
    /// 更新数据
    /// </summary>
    /// <param name="setting"></param>
    /// <returns></returns>
    public static Setting Update(this Setting setting)
    {
        FreeSql.Update(setting).ExecuteEffects();
        return setting;
    }

    /// <summary>
    /// 显示设置窗口
    /// </summary>
    public static void Show()
    {
        var form = new SettingsForm();
        form.ShowDialog();
    }
}